const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');

const port = process.argv[2] || '80';

http.createServer(function (req, res) {

  const url = new URL(req.url, `http://${req.headers.host}`);

  if (url.pathname == '/' || url.pathname == '/index') {
    fs.readFile('./index.html', "binary", (err, file) => {

      if (err) {
        res.writeHead(500, { "Content-Type": "text/plain" });
        res.write(err + "\n");
        res.end();
        console.error('500: ' + filename);
      } else {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write(file, 'binary');
        res.end();
        console.log('用户请求主页');
      }
    })
    return;
  }

  if (url.pathname == '/upload' && req.method.toLowerCase() == 'post') {
    console.log('post', req.url);
    dataTransferProcess(req, res);
    return;
  }

  res.writeHead(404, { 'Content-Type': 'text/plain' });
  res.write('404 Not Found\n');
  res.end();
  console.error('404: ' + filename);
}).listen(parseInt(port, 10));


console.log('Static file server running at\n  => http://localhost:' + port + '/\nCTRL + C to shutdown');


function dataTransferProcess(req, res) {
  let expect = 'sp';
  const begin = new Date();
  const filename = begin.toTimeString() + '.txt';
  let sp, cont, type;
  let total = 0;
  let count = 0;
  req.on('data', function (buf) {
    count++;
    fs.appendFileSync(filename, buf);
    while (true) {
      switch (expect) {
        case 'sp':
          var idx = buf.indexOf('\r\n');
          if (idx == -1) return;
          sp = buf.slice(0, idx).toString();
          buf = buf.slice(idx + 2);
          console.log('sp:', sp);
          expect = 'content';
          break;
        case 'content':
          var idx = buf.indexOf('\r\n');
          cont = buf.slice(0, idx).toString();
          console.log('content:', cont);
          if (/Content-Disposition: ?form-data;.*filename="/.test(cont)) {
            expect = 'type';
            buf = buf.slice(idx + 2);
          } else {
            expect = 'value';
            buf = buf.slice(idx + 4);
          }
          break;
        case 'value':
          var idx = buf.indexOf('\r\n');
          value = buf.slice(0, idx).toString();
          buf = buf.slice(idx + 2);
          console.log('value:', value);
          expect = 'sp';
          break;
        case 'type':
          var idx = buf.indexOf('\r\n');
          type = buf.slice(0, idx).toString();
          buf = buf.slice(idx + 4);
          console.log('type:', type);
          expect = 'end';
          break;
        case 'end':
          var idx = buf.indexOf('\r\n' + sp);
          process.stdout.write('.');
          if (idx >= 0) {
            total += idx;
          } else {
            total += buf.length;
          }
          return;
      }
    }
  }).on('end', function () {
    console.log('\ntotal:', total);
    console.log('\ncount:', count);
    let spendTm = new Date() - begin;
    res.end(`<head>
            <meta http-equiv='Content-Type' content='text/html; charset=gb2312' />
            </head>
            <body><p>${cont}</p>
            <p>total: ${total}</p>
            <p>upload speed: ${parseInt((total * 8) / (spendTm / 1000))} bps</p>
            <p>upload speed: ${parseInt((total / 1024 / 1024) / (spendTm / 1000))} Mbyte per second</p>
            </body>`);
  });
}